package com.hq.ims.data.service;

import com.hq.ims.data.config.verification.VdAdd;
import com.hq.ims.data.config.verification.VdEdit;
import com.hq.ims.data.dao.PermissionRoleMapper;
import com.hq.ims.data.entity.*;
import com.hq.ims.data.entityenum.EnumGroupType;
import com.hq.ims.data.utils.ErrMsgConstant;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.ims.data.vo.PermissionRoleMapstruct;
import com.hq.mybatis.base.BaseService;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.utils.exception.CommonException;
import com.hq.utils.util.BooleanUtils;
import com.hq.utils.util.ListUtils;
import com.hq.utils.util.ObjectUtils;
import com.hq.utils.util.StringUtils;
import com.hq.web.utils.SpringBootValidateUtils;
import lombok.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * jiang bai ping
 *
 * @Email 526666031@qq.com
 * @Detail 角色服务实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BasePermissionRoleService extends BaseService<PermissionRoleMapper, PermissionRole> {

    @Resource
    private BasePermissionMapRoleUserService basePermissionMapRoleUserService;
    @Resource
    private BasePermissionMapAuthorityMenuService basePermissionMapAuthorityMenuService;
    @Resource
    private BasePermissionMapAuthorityRoleService basePermissionMapAuthorityRoleService;
    @Resource
    private BaseCompanyService baseCompanyService;
    @Resource
    private BasePermissionGroupService basePermissionGroupService;

    /**
     * 分页
     */
    public List<PermissionRoleMapstruct.PermissionRoleVo> getPage(
            RequestPage page,
            PermissionRoleMapstruct.PageSearchVo searchVo
    ) {
        //获取列表
        this.lambdaQuery()
                .like(StringUtils.isNotEmpty(searchVo.getRoleName()), PermissionRole::getRoleName, searchVo.getRoleName())
                .eq(StringUtils.isNotEmpty(searchVo.getPermissionGroupId()), PermissionRole::getPermissionGroupId, searchVo.getPermissionGroupId())
                .eq(StringUtils.isNotEmpty(searchVo.getCompanyId()), PermissionRole::getCompanyId, searchVo.getCompanyId())
                .page(page);

        List<PermissionRole> records = page.getRecords();
        List<PermissionRoleMapstruct.PermissionRoleVo> voList = PermissionRoleMapstruct.INSTANCE.toPermissionRoleVoList(records);

        return voList;
    }


    /**
     * 校验角色是否存在,使用前请校验好参数
     */
    public PermissionRole checkRoleIsExist(String roleId) {
        if (StringUtils.isEmpty(roleId)) {
            throw CommonException.build(ErrMsgConstant.PARAM_INPUT_ERROR);
        }
        PermissionRole permissionRole = this.getById(roleId);
        if (permissionRole == null) {
            throw CommonException.build("该角色不存在,无法进行其他操作,请联系管理员。角色id：" + roleId);
        }
        return permissionRole;
    }

    /**
     * 添加角色,同一家公司不能有相同的角色
     */
    @Transactional(rollbackFor = Exception.class)
    public void addRole(PermissionRoleMapstruct.SaveVo saveVo) {
        //验证
        SpringBootValidateUtils.validate(saveVo, VdAdd.class);
        //验证公司
        Company company = baseCompanyService.getById(saveVo.getCompanyId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);
        //验证组
        PermissionGroup permissionGroup = basePermissionGroupService.getById(saveVo.getPermissionGroupId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.PERMISSION_ROLE_GROUP_NOT_EXISTS);
        BooleanUtils.isTrueThrow(permissionGroup.getGroupType() != EnumGroupType.Role, ErrMsgConstant.PERMISSION_ROLE_GROUP_NOT_EXISTS);

        //检查同一家公司同一个部门是否有相同的角色
        boolean existsName = this.isExistsName(saveVo.getCompanyId(), saveVo.getRoleName(), saveVo.getPermissionRoleId());
        BooleanUtils.isTrueThrow(existsName, ErrMsgConstant.PERMISSION_ROLE_NAME_EXISTS);

        PermissionRole permissionRole = new PermissionRole();
        permissionRole.setCompanyId(company.getCompanyId());
        permissionRole.setPermissionGroupId(saveVo.getPermissionGroupId());
        permissionRole.setRoleName(saveVo.getRoleName());
        permissionRole.setIsAllowEdit(true);
        permissionRole.setOnlyKey(StringUtils.EMPTY);

        //添加角色
        boolean bl = permissionRole.insert();
        BooleanUtils.isFalseThrow(bl, ErrMsgConstant.OPERATION_FAILURE);
    }

    /**
     * 检查角色名称是否重复
     */
    public boolean isExistsName(
            String companyId,
            String roleName,
            String excludeId
    ) {
        return this.lambdaQuery()
                .eq(PermissionRole::getCompanyId, companyId)
                .eq(PermissionRole::getRoleName, roleName)
                .eq(PermissionRole::getPermissionRoleId, excludeId)
                .ne(StringUtils.isNotEmpty(excludeId), PermissionRole::getPermissionRoleId, excludeId)
                .count() > 0;
    }

    /**
     * 更新角色
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(
            PermissionRoleMapstruct.SaveVo saveVo
    ) {
        //验证
        SpringBootValidateUtils.validate(saveVo, VdEdit.class);
        //验证公司
        Company company = baseCompanyService.getById(saveVo.getCompanyId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);
        //验证组
        PermissionGroup permissionGroup = basePermissionGroupService.getById(saveVo.getPermissionGroupId());
        ObjectUtils.isNullThrow(permissionGroup, ErrMsgConstant.PERMISSION_ROLE_GROUP_NOT_EXISTS);
        BooleanUtils.isTrueThrow(permissionGroup.getGroupType() != EnumGroupType.Role, ErrMsgConstant.PERMISSION_ROLE_GROUP_NOT_EXISTS);
        //验证数据
        PermissionRole permissionRole = this.getById(saveVo.getPermissionRoleId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.PERMISSION_ROLE_NAME_EXISTS);
        //检查同一家公司同一个部门是否有相同的角色
        boolean existsName = this.isExistsName(saveVo.getCompanyId(), saveVo.getRoleName(), saveVo.getPermissionRoleId());
        BooleanUtils.isTrueThrow(existsName, ErrMsgConstant.PERMISSION_ROLE_NAME_EXISTS);

        permissionRole.setCompanyId(company.getCompanyId());
        permissionRole.setPermissionGroupId(saveVo.getPermissionGroupId());
        permissionRole.setRoleName(saveVo.getRoleName());
        permissionRole.setIsAllowEdit(true);
        permissionRole.setOnlyKey(StringUtils.EMPTY);

        //添加角色
        boolean bl = permissionRole.updateById();
        BooleanUtils.isFalseThrow(bl, ErrMsgConstant.OPERATION_FAILURE);
    }

    /**
     * 删除角色
     */
    public void delByRoleId(String permissionRoleId) {
        PermissionRole permissionRole = this.getById(permissionRoleId);
        if (permissionRole == null) {
            return;
        }
        //1.删除角色-权限点关联数据
        basePermissionMapRoleUserService.delByRoleIdAndCompanyId(permissionRole.getPermissionRoleId(), permissionRole.getCompanyId());
        //2.删除组-角色关联数据
        basePermissionMapAuthorityRoleService.delByRoleId(permissionRoleId);
        //3.删除角色本身角色数据
        this.removeById(permissionRoleId);
    }

    /**
     * 根据组id获取该组中所有角色
     */
    public List<PermissionRoleMapstruct.PermissionRoleVo> getByAuthId(@NonNull List<String> authIdList) {

        List<PermissionMapAuthorityRole> permissionMapAuthorityRoleList = basePermissionMapAuthorityRoleService.getByAuthIdList(authIdList);
        if (ListUtils.isNotExistsEle(permissionMapAuthorityRoleList)) {
            return ListUtils.newEmptyList();
        }
        List<String> roleidList = permissionMapAuthorityRoleList.stream().map(PermissionMapAuthorityRole::getPermissionRoleId).collect(Collectors.toList());
        List<PermissionRole> roleList = this.lambdaQuery().in(PermissionRole::getPermissionRoleId, roleidList).list();

        List<PermissionRoleMapstruct.PermissionRoleVo> voList = PermissionRoleMapstruct.INSTANCE.toPermissionRoleVoList(roleList);
        return voList;
    }

    public PermissionRoleMapstruct.PermissionRoleVo getByRoleIdAndCompanyId(
            @NonNull String roleId,
            @NonNull String companyId
    ) {
        PermissionRole permissionRole = this.lambdaQuery()
                .eq(PermissionRole::getPermissionRoleId, roleId)
                .eq(PermissionRole::getCompanyId, companyId)
                .last(LocalConstant.LIMIT_1)
                .one();
        PermissionRoleMapstruct.PermissionRoleVo vo = PermissionRoleMapstruct.INSTANCE.toPermissionRoleVo(permissionRole);
        return vo;
    }

    /**
     * 这个组下面有多少条权限数据
     */
    public long groupDataCount(String permissionGroupId) {
        Long count = this.lambdaQuery().eq(PermissionRole::getPermissionGroupId, permissionGroupId).count();
        return count.longValue();
    }

    /**
     * 这个组是否存在数据
     */
    public boolean groupDataIsExists(String permissionGroupId) {
        return groupDataCount(permissionGroupId) > 0;
    }

    /**
     * 获取角色和绑定的权限ID
     *
     * @param permissionRoleId 角色以ID
     */
    public PermissionRoleMapstruct.PermissionRoleVo getBindAuthDetail(String permissionRoleId) {
        PermissionRole permissionRole = this.getById(permissionRoleId);
        PermissionRoleMapstruct.PermissionRoleVo vo = PermissionRoleMapstruct.INSTANCE.toPermissionRoleVo(permissionRole);
        if (vo == null) {
            return vo;
        }
        //获取权限
        List<String> authIdListByRoleIdList = basePermissionMapAuthorityRoleService.getAuthIdListByRoleIdList(Arrays.asList(permissionRole.getPermissionRoleId()));
        vo.setPermissionAuthorityIdList(authIdListByRoleIdList);
        return vo;
    }


    @Transactional(rollbackFor = Exception.class)
    public void delByCompanyId(String companyId) {
        this.lambdaUpdate().eq(PermissionRole::getCompanyId, companyId).remove();
    }
}
